#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QBoxLayout>
#include <QLabel>
#include <QPushButton>
#include <QLCDNumber>
#include <QListView>
#include <QtNetwork>
#include "logger.h"
#include "parksystem.h"
#include "validatecard.h"
#include "cardcontrol.h"
#include <QTime>

#include <vector>
#include <algorithm>

#define MAX_NUM_EACH_COLUMN 10
#define MOVE_SHAPE_SIZE 40

namespace Ui {
class MainWindow;
class ValidateCard;
class ParkSystem;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

    /**
     * @brief restoreSqlDate - seems no use
     */
    void restoreSqlDate();
    void userInterface();
    void setPreTakenArea(Card * card);
    /**
     * @brief setTakenArea - change the color and text of button which is taken
     * @param card
     */
    void setTakenArea(Card card);
    void setLeaveArea(Card * card);

//    QString randomGenerateCardId();
    int getTimeRecord();

signals:
    void randomCarSignals();
    void verifyEntranceSignals();
    void verifyExitSignals();
    void selectExitCarSignals();

private:

    // UI component
    // Panel Component
    QLabel      *userh;
    QPushButton *cardS;
    QLabel      *id;
    QLabel      *name;
    QLCDNumber  *plotNum;
    QListView   *logUserInfo;
    QListView   *logMotorInfo;

    // Monitor component
    QHBoxLayout *parkAreaUp;
    QHBoxLayout *parkAreaDown;
    QHBoxLayout *RoadPath;
    QPushButton *Entence;
    QPushButton *Exit;
    QPushButton *ExitTakenArea;
    QPushButton *entenceVerify;
    QPushButton *exitVerify;
    QLCDNumber  *freeArea;
    QPushButton *RandomCar;
    QString      randomCardId;
    QString      leaveCardId;
    QPushButton *willingToLeaveCar;
    QLabel      *MessageBox;
    QLabel      *timeDisplayer;

    ValidateCard validateCard;
    ParkSystem   parkSystem;
    QTimer      *timer;
    QTimer      *timerExit;
    QTimer      *painterTimerEntence;
    QTimer      *painterTimerExit;
    QTimer      *randomTimerEntence;
    QTimer      *randomTimerExit;

    QTimer      *timeRecorder; // record time during total process
    QTime       *timeRecord;
    std::vector <Card*> cardList;

    QPushButton *buttonArray[2][MAX_NUM_EACH_COLUMN];
    QPushButton *movementPathArray[MAX_NUM_EACH_COLUMN];
    int          initialGeometryX;
    int          initialGeometryY;
    int          animationParkPosition;
    int currentEntenceMovementPosition;
    int currentExitMovementPosition;
    int fromPosition;
    int toPosition;
    int waitTwoSecondEntence;
    int waitTwoSecondExit;
    bool isEntencing;
    bool isExiting;

    int entranceOn = 0;

    std::vector<CardControl*> forwardCards;
    std::vector<CardControl*> backwardCards;

    //Log output
    QStringListModel *userInfoModel;
    QStringListModel *motorInfoModel;
    Logger           *userLog;
    Logger           *motorLog;

    // Base service
    Ui::MainWindow *ui;
    QUdpSocket     *receiver;

    /**
     * @brief bindUI
     */
    void bindComponent();

    /**
     * @brief MainWindow::loadStyleSheet - load .qss file to intialize
     * @param styleSheetFile - path of file
     */
    void loadStyleSheet(const QString &styleSheetFile);

    /**
     * @brief buildInterface - initialization
     */
    void buildInterface();

    /**
     * @brief buildInterface
     * @param user
     */
    void buildInterface(Card *card);

    void painterEntrance();
    void painterExit();
//    void automaticRun();

public slots:
    /**
     * @brief processPendingDatagram
     */
//    void processPendingDatagram();
    void eventTrigger();

    /**
     * @brief timeDone - change components back when actions end
     */
    void timeDone();
    void timeExitDone();
//    void randomCar();
    void disposalEntrance();
    void disposalExit();
    void ParkAnimationFinished();
//    void disposalLeaveSelect();

    void randomTimerEntranceDone();
    void randomTimerExitDone();


    void movePathPainter();
    void doMovePath(int p);
    void doLeavePath(int p);
    void doArrive(int p);
    void doLeave(int p);
};

#endif // MAINWINDOW_H
